package com.handinfo.android.core.resource;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.content.SharedPreferences;

import com.handinfo.android.DWGameManager;
import com.handinfo.android.utils.Tools;

public class ResourceManager
{
	private static ResourceManager sInstance;
	private String m_resDir = "res";
	public int m_load_percent = 0;
	public IORWFile mRW;
	private SharedPreferences m_miss_res_list;

	private ResourceManager()
	{
	}

	public static ResourceManager getInstance()
	{
		if (sInstance == null) {
			sInstance = new ResourceManager();
			sInstance.mRW = new IORWFile();
		}
		return sInstance;
	}

	/**
	 * 根据head和data，往存储介质里写入资源
	 * 
	 * @param head
	 * @param data
	 */
	public void writeResource(ResHead head, byte[] data) throws Exception
	{
		StringBuffer buffer = new StringBuffer(DWGameManager.s_res_dir);
		switch (head.m_type) {
			case DWSerializableFactory.RESOURCE_TYPE_ANIM:
				buffer.append(DWSerializableFactory.DIR_ANIM);
				break;
			case DWSerializableFactory.RESOURCE_TYPE_BG:
				buffer.append(DWSerializableFactory.DIR_BG);
				break;
			case DWSerializableFactory.RESOURCE_TYPE_PNG:
				buffer.append(DWSerializableFactory.DIR_IMG);
				break;
			case DWSerializableFactory.RESOURCE_TYPE_SCENE:
				buffer.append(DWSerializableFactory.DIR_SCENE);
				break;
			case DWSerializableFactory.RESOURCE_TYPE_SOUND:
				buffer.append(DWSerializableFactory.DIR_SOUND);
				break;
			default:
				return;
		}

		String path = buffer.toString();

		File file = new File(path);
		if (!file.exists()) {
			File parent = file.getParentFile();
			if (!parent.exists()) {
				parent.mkdirs();
			}
			file.createNewFile();
		}

		FileOutputStream fos = new FileOutputStream(file);
		fos.write(data);
		fos.flush();
		fos.close();
	}

	/**
	 * 根据head获取对象并且放入到res中
	 * 
	 * @param res
	 * @param head
	 * @return
	 * @throws IOException
	 */
	public DWSerializable getSerializeObject(Resource res, ResHead head)
	{
//		byte[] data = null;
////		data = mRW.readResource(head);
//		InputStream is = openStream(head.m_url);
//		if (is == null) {
//			data = mRW.readResource(head);
//			if (data == null) {
//				Tools.debugPrintln("欠缺资源，请修复游戏！！！！");
//			}
//		}
//		else {
//			try {
//				int size = is.available();
//				data = new byte[size];
//				is.read(data);
//				is.close();
//			}
//			catch (Exception ex) {
//				Tools.debugPrintln("getSerializeObject异常：" + head.m_url);
//				Tools.debug(ex);
//			}
//		}
		
		byte[] data = getResourceData(head);

		if (data != null) {
			return DWSerializableFactory.convert(res, head, data);
		}
		else {
			return null;
		}
	}
	
	/**
	 * 根据ResourceList生成Resource
	 * 
	 * @param list
	 * ResourceList
	 * @return Resource
	 */
	public Resource loadResource(Resource res, ResourceList list)
	{
		ResHead head;
		while (list.hasMoreElements()) {
			head = list.nextElement();
			loadResource(res, head);
		}
		return res;
	}
	

	/**
	 * 根据head载入资源到res中
	 * 
	 * @param res
	 * @param head
	 * @return
	 * @throws IOException
	 */
	public DWSerializable loadResource(Resource res, ResHead head)
	{
		DWSerializable inst = res.getResource(head);
		if (inst != null)
			return inst;
		inst = getSerializeObject(res, head);
		if (inst != null) {
			res.put(head, inst);
		}
		return inst;
	}

	/**
	 * 
	 * 
	 * @param res
	 * @param head
	 * @param data
	 * @return
	 */
	public DWSerializable loadResource(Resource res, ResHead head, byte[] data)
	{
		DWSerializable inst = res.getResource(head);
		if (inst != null)
			return inst;
		inst = DWSerializableFactory.convert(res, head, data);
		if (inst != null) {
			res.put(head, inst);
		}
		else {
			Tools.debugPrintln("欠缺资源，请修复游戏！！！");
		}
		return inst;
	}

	/**
	 * 根据list更新res
	 * 
	 * @param old
	 * @param list
	 */
	public void updateResource(Resource res, ResourceList list)
	{
		ResourceList rxor = res.rxor(list); // 查找出res中的数据未列在list名单上的，用在后面删除
		ResourceList xor = res.xor(list); // 查找出res中在list名单上没有的数据， 用在加载新数据
		list.reset();
		ResHead head;
		while (rxor.hasMoreElements()) {
			head = rxor.nextElement();
			res.remove(head);
		}
		int length = xor.size();
		int index = 0;
		while (xor.hasMoreElements()) {
			head = xor.nextElement();
			loadResource(res, head);
			index++;
		}
		m_load_percent = 100;
	}

	/**
	 * 从res中移除指定head的资源
	 * 
	 * @param res
	 * @param head
	 */
	public void removeResource(Resource res, ResHead head)
	{
		res.remove(head);
	}

	/**
	 * 从res中移除list中的所有资源
	 * 
	 * @param res
	 * @param list
	 */
	public void removeResource(Resource res, ResourceList list)
	{
		ResHead head;
		while (list.hasMoreElements()) {
			head = list.nextElement();
			res.remove(head);
		}
	}

	/**
	 * 移除res中的所有资源
	 * 
	 * @param res
	 */
	public void removeAllResource(Resource res)
	{
		res.clean();
	}

	public void setResDir(String resDir)
	{
		m_resDir = resDir;
	}

	public String getResDir()
	{
		return m_resDir;
	}

	/**
	 * 根据file得到对应文件的二进制流（只针对本地文件）
	 * 
	 * @param file
	 * @return
	 */
	public InputStream openStream(String file)
	{
		StringBuffer buff = new StringBuffer(getResDir());
		buff.append(file);
		try {
			return DWGameManager.getInstance().getCurrentActivity().getAssets()
					.open(buff.toString());
		}
		catch (Exception e) {
//			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 获得资源数据
	 * @param path
	 * @return
	 */
	public byte[] getResourceData(ResHead head)
	{
		if (head == null) {
			Tools.debugPrintln("getResourceData--ResHead为null");
			return null;
		}
		
		byte[] data = null;
		
		try {
			File file = new File(DWGameManager.s_res_dir + head.m_url);
			if (!file.exists()) {
				Tools.debugPrintln("无法找到此资源文件--" + head.m_url);
				return null;
			}

			FileInputStream is = new FileInputStream(file);
			if (is != null) {
				int size = is.available();
				data = new byte[size];
				is.read(data);
				is.close();
			}
			is = null;
		}
		catch (Exception ex) {
			Tools.debug(ex);
		}
		
		return data;
	}
	
	/**
	 * 从资源目录中获得资源数据流
	 * @param path
	 * @return
	 */
	public InputStream readResourceFile(String path)
	{
		try {
			File file = new File(path);
			FileInputStream fis = new FileInputStream(file);
			return fis;
		}
		catch (FileNotFoundException e) {
			Tools.debug(e);
			Tools.debugPrintln("ReadResourceFile Error!----" + path);
		}
		catch (Exception e) {
			Tools.debug(e);
			Tools.debugPrintln("ReadResourceFile Error!----" + path);
		}
		return null;
	}
}
